// 1. 定义菜单名称枚举
const MENU_NAME = {
    RISK_DYNAMIC: 'risk_dynamic',
    INTERNAL_EVALUATION: 'internal_evaluation',
    BUSINESS_ANALYSIS: 'business_analysis',
    FINANCIAL_MONITOR: 'financial_monitor',
    OPERATION_INSIGHT: 'operation_insight',
    MARKET_TREND: 'market_trend',
    COMPLIANCE_CHECK: 'compliance_check',
    SECURITY_ALERT: 'security_alert',
    CUSTOM_DASHBOARD: 'custom_dashboard',
};

// 2. 创建枚举值的反向映射表
const MENU_REVERSE_MAP = Object.entries(MENU_NAME).reduce(
    (acc, [key, value]) => {
        acc[value] = key;
        return acc;
    },
    {}
);

// 3. 定义页面到Helper的映射关系（使用MENU_NAME的键）
const PAGE_HELPER_MAP = {
    [MENU_NAME.RISK_DYNAMIC]: 'eh1', // 风险动态
    [MENU_NAME.INTERNAL_EVALUATION]: 'eh1', // 内部评估
    [MENU_NAME.BUSINESS_ANALYSIS]: 'eh2', // 业务分析
    [MENU_NAME.FINANCIAL_MONITOR]: 'eh2', // 财务监控
    [MENU_NAME.OPERATION_INSIGHT]: 'eh3', // 运营洞察
    [MENU_NAME.MARKET_TREND]: 'eh3', // 市场趋势
    [MENU_NAME.COMPLIANCE_CHECK]: 'eh4', // 合规检查
    [MENU_NAME.SECURITY_ALERT]: 'eh4', // 安全告警
    [MENU_NAME.CUSTOM_DASHBOARD]: 'eh1', // 自定义仪表盘
};

// 4. 增强企业服务类，支持菜单名称作为标识
class EnterpriseService {
    /**
     * 根据菜单名称查询企业
     * @param {string|Object} menuIdentifier - 可以是MENU_NAME枚举值或枚举键
     * @param {string} enterprise - 企业名称
     */
    static async checkEnterprise(menuIdentifier, enterprise) {
        // 获取对应的Helper标识
        const helperId = this.resolveHelperId(menuIdentifier);

        if (!helperId || !enterpriseHelpers[helperId]) {
            throw new Error(`无效菜单标识或Helper未配置: ${menuIdentifier}`);
        }

        return await enterpriseHelpers[helperId].existEnterprise(enterprise);
    }

    /**
     * 解析菜单标识到Helper ID
     * @param {string|Object} menuIdentifier
     * @returns {string|null}
     */
    static resolveHelperId(menuIdentifier) {
        // 情况1: 传入的是MENU_NAME的键（如 'RISK_DYNAMIC'）
        if (menuIdentifier in MENU_NAME) {
            const menuValue = MENU_NAME[menuIdentifier];
            return PAGE_HELPER_MAP[menuValue] || null;
        }

        // 情况2: 传入的是MENU_NAME的值（如 'risk_dynamic'）
        if (menuIdentifier in PAGE_HELPER_MAP) {
            return PAGE_HELPER_MAP[menuIdentifier];
        }

        // 情况3: 传入的是MENU_NAME枚举键的反向映射值
        if (menuIdentifier in MENU_REVERSE_MAP) {
            const menuKey = MENU_REVERSE_MAP[menuIdentifier];
            return this.resolveHelperId(menuKey);
        }

        return null;
    }

    // ... 其他方法保持不变 ...
}

// 5. 使用示例（多种调用方式）
async function exampleUsage() {
    // 方式1: 使用MENU_NAME的键
    const result1 = await EnterpriseService.checkEnterprise(
        'RISK_DYNAMIC',
        '阿里巴巴'
    );

    // 方式2: 使用MENU_NAME的值
    const result2 = await EnterpriseService.checkEnterprise(
        'risk_dynamic',
        '腾讯'
    );

    // 方式3: 使用反向映射（如果需要）
    const result3 = await EnterpriseService.checkEnterprise(
        'risk_dynamic', // 注意：这个值在MENU_NAME中不存在，但会尝试反向查找
        '百度'
    );

    console.log(`阿里巴巴存在状态: ${result1}`);
    console.log(`腾讯存在状态: ${result2}`);
    console.log(`百度存在状态: ${result3}`);
}

class ApiCache {
    constructor(options = {}) {
        this.cache = new Map();
        this.pendingRequests = new Map();
        this.maxSize = options.maxSize || 5;
        this.expireTime = options.expireTime || 0; // 0表示永不过期
    }

    generateKey(params) {
        return JSON.stringify(params);
    }

    async getData(params) {
        const key = this.generateKey(params);

        // 检查缓存是否存在且未过期
        const cachedEntry = this.cache.get(key);
        if (cachedEntry) {
            if (!this.isExpired(cachedEntry.timestamp)) {
                return cachedEntry.data;
            } else {
                this.cache.delete(key); // 过期删除
            }
        }

        // 检查是否有正在进行的请求
        if (this.pendingRequests.has(key)) {
            return this.pendingRequests.get(key);
        }

        // 创建新的请求
        const requestPromise = this.fetchRemoteData(params)
            .then((data) => {
                // 缓存结果
                this.cache.set(key, {
                    data,
                    timestamp: Date.now(),
                });
                // 清理缓存（过期和超大小）
                this.cleanCache();
                this.pendingRequests.delete(key);
                return data;
            })
            .catch((err) => {
                this.pendingRequests.delete(key);
                throw err;
            });

        this.pendingRequests.set(key, requestPromise);
        return requestPromise;
    }

    isExpired(timestamp) {
        return this.expireTime && Date.now() - timestamp > this.expireTime;
    }

    cleanCache() {
        // 清理过期缓存
        for (const [key, entry] of this.cache) {
            if (this.isExpired(entry.timestamp)) {
                this.cache.delete(key);
            }
        }

        // 清理超过大小的缓存（按时间戳升序，删除最早的）
        if (this.cache.size > this.maxSize) {
            const sortedEntries = [...this.cache.entries()].sort(
                (a, b) => a[1].timestamp - b[1].timestamp
            );
            for (let i = 0; i < sortedEntries.length - this.maxSize; i++) {
                this.cache.delete(sortedEntries[i][0]);
            }
        }
    }

    async fetchRemoteData(params) {
        // 实际网络请求，这里用模拟
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve({ result: `Data for ${JSON.stringify(params)}` });
            }, 500);
        });
    }
}

// 共享缓存单例
const repofficeCache = new ApiCache({ maxSize: 20, expireTime: 3600000 });

class EnterpriseHelper {
    constructor(apiEndpoint, privateParams, cacheOptions = {}) {
        this.apiEndpoint = apiEndpoint;
        this.privateParams = privateParams;
        this.apiCache = new ApiCache({
            maxSize: 5,
            expireTime: 600000,
            ...cacheOptions,
        });
    }

    async existEnterprise(enterprise) {
        // 从共享缓存获取公共参数
        const sharedParams = await repofficeCache.getData({
            type: 'common_params',
        });

        // 组合请求参数
        const requestParams = {
            ...this.privateParams,
            ...sharedParams,
            enterprise,
        };

        // 使用私有缓存获取数据
        return this.apiCache.getData({
            url: this.apiEndpoint,
            params: requestParams,
        });
    }
}
